package libtool65.o65;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;

public class Header {
//	.byt $01,$00		; non-C64 marker
//	.byt $6f, $36, $35	; "o65" MAGIC number!
	private final static int header_magic[] = { 0x01, 0x00, 0x6f, 0x36, 0x35 };
//	.byt 0			; version
	private int version = -1;
//	.word mode		; mode word
	private Mode mode = new Mode();
//	.size tbase		; address to which text is assembled to originally
//  .size tlen		; length of text segment
	private SegmentDef text = new SegmentDef();
//	.size dbase		; originating address for data segment
//	.size dlen		; length of data segment
	private SegmentDef data = new SegmentDef();
//	.size bbase		; originating address for bss segment
//	.size blen		; length of bss segment
	private SegmentDef bss = new SegmentDef();
//	.size zbase		; originating address for zero segment
//	.size zlen		; length of zero segment
	private SegmentDef zp = new SegmentDef();
//	.size stack		; minimum needed stack size, 0= not known.
	private int stack_size = 0;

	public void read(InputStream file) throws IOException, FormatException {
		int ch;
		for (int i = 0; i < header_magic.length; i++)
		{
			ch = file.read();
			if (ch != header_magic[i])
				throw new FormatException(i, header_magic[i], ch);
		}
		version = file.read();
		mode.read(file);
		text.read(file, mode);
		data.read(file, mode);
		bss.read(file, mode);
		zp.read(file, mode);
		stack_size = mode.readSize(file);
	}

	public void dumpInfo(PrintStream out) {
		out.println("Version: "+version);
		mode.dumpInfo(out);
		text.dumpInfo("TEXT", out);
		data.dumpInfo("DATA", out);
		bss.dumpInfo("BSS", out);
		zp.dumpInfo("ZP", out);
		out.println("Stack: "+stack_size);
	}

	public SegmentDef getTextSegment() {
		return text;
	}

	public SegmentDef getDataSegment() {
		return data;
	}

	public Mode getMode() {
		return mode;
	}

	public SegmentDef getBssSegment() {
		return bss;
	}

	public SegmentDef getZpSegment() {
		return zp;
	}
}
